package com.nvelickovic10.snake.gui;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

import com.nvelickovic10.snake.beans.food.Bonus;
import com.nvelickovic10.snake.beans.game.GameSave;
import com.nvelickovic10.snake.beans.snake.Direction;
import com.nvelickovic10.snake.beans.snake.Snake;
import com.nvelickovic10.snake.beans.snake.SnakeBits;
import com.nvelickovic10.snake.main.AppCore;

public class GameWindow extends JFrame {

	private static final long serialVersionUID = -5429621693872963811L;
	private boolean disposed, disposingg;

	public GameWindow() {
		disposed = false;
		setDisposingg(false);
		setTitle("Snake");
		try {
			setIconImage(ImageIO.read(new File("png/snake.png")));
		} catch (IOException e) {
			e.printStackTrace();
		}
		addWindowListener(new WindowListener() {

			@Override
			public void windowOpened(WindowEvent arg0) {
				// TODO Auto-generated method stub

			}

			@Override
			public void windowIconified(WindowEvent arg0) {
				// TODO Auto-generated method stub

			}

			@Override
			public void windowDeiconified(WindowEvent arg0) {
				// TODO Auto-generated method stub

			}

			@Override
			public void windowDeactivated(WindowEvent arg0) {
				// TODO Auto-generated method stub

			}

			@Override
			public void windowClosing(WindowEvent arg0) {
				disposingg = true;
				// int resp = JOptionPane.showConfirmDialog(null, "SAVE GAME?",
				// "CLOSING", JOptionPane.YES_NO_OPTION);
				// if (resp == JOptionPane.YES_OPTION) {
				// GameSave gs = new GameSave();
				// gs.save();
				// }
				disposed = true;
			}

			@Override
			public void windowClosed(WindowEvent arg0) {
				// TODO Auto-generated method stub

			}

			@Override
			public void windowActivated(WindowEvent arg0) {
				// TODO Auto-generated method stub

			}
		});
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		setSize(AppCore.getInstance().getWidth(), AppCore.getInstance()
				.getHeight() + 20);
		setResizable(false);
		setLocationRelativeTo(null);
		addKeyboardListener();
		repaint();
		setVisible(true);
	}

	private void addKeyboardListener() {
		addKeyListener(new KeyListener() {

			@Override
			public void keyTyped(KeyEvent arg0) {
				// TODO Auto-generated method stub

			}

			@Override
			public void keyReleased(KeyEvent arg0) {
				int keyCode = arg0.getKeyCode();
				switch (keyCode) {
				case KeyEvent.VK_Q:
					AppCore.getInstance().returnSpeed();
					AppCore.getInstance().setSpaceDown(false);
					break;
				default:
					break;
				}

			}

			@Override
			public void keyPressed(KeyEvent arg0) {
				if (arg0.getKeyCode() == KeyEvent.VK_P) {
					AppCore.getInstance().setPaused(true);
				}
				if (arg0.getKeyCode() == KeyEvent.VK_L) {
					AppCore.getInstance().setLoading(true);
					GameSave gs = new GameSave();
					gs.load();
					AppCore.getInstance().setLoading(false);
				}
				if (AppCore.getInstance().isGameOn()
						&& !AppCore.getInstance().isPaused()) {
					int keyCode = arg0.getKeyCode();
					switch (keyCode) {
					case KeyEvent.VK_Q:
						AppCore.getInstance().setSpeed(
								AppCore.getInstance().getCheatSpeed());
						AppCore.getInstance().setSpaceDown(true);
						break;
					case KeyEvent.VK_UP:
						if (Snake.getInstance().getHead()
								.setDirrection(Direction.UP))
							AppCore.getInstance().getEngine().interrupt();
						break;
					case KeyEvent.VK_DOWN:
						if (Snake.getInstance().getHead()
								.setDirrection(Direction.DOWN))
							AppCore.getInstance().getEngine().interrupt();
						break;
					case KeyEvent.VK_LEFT:
						if (Snake.getInstance().getHead()
								.setDirrection(Direction.LEFT))
							AppCore.getInstance().getEngine().interrupt();
						break;
					case KeyEvent.VK_RIGHT:
						if (Snake.getInstance().getHead()
								.setDirrection(Direction.RIGHT))
							AppCore.getInstance().getEngine().interrupt();
						break;
					}
				}
			}
		});
	}

	@Override
	public void paint(Graphics g) {
		BufferedImage image = new BufferedImage(AppCore.getInstance()
				.getWidth(), AppCore.getInstance().getHeight() + 20,
				BufferedImage.TYPE_INT_ARGB);
		Graphics2D d2d = image.createGraphics();
		d2d.setColor(Color.WHITE);
		d2d.fillRect(0, 0, image.getWidth(), image.getHeight());
		paintBoard(d2d);
		AppCore.getInstance().getFood().paintBit(d2d);
		paintBonuses(d2d);
		paintSnake(d2d);
		paintWalls(d2d);
		d2d.setColor(Color.BLACK);
		d2d.drawString(
				"Score: " + String.valueOf(AppCore.getInstance().getPoints()),
				10, AppCore.getInstance().getHeight() + 2);
		d2d.drawString(
				"Size: " + String.valueOf(Snake.getInstance().getBody().size()),
				125, AppCore.getInstance().getHeight() + 2);
		d2d.drawString("Username: " + AppCore.getInstance().getUsername(), 10,
				AppCore.getInstance().getHeight() + 12);
		Graphics2D g2d = (Graphics2D) g;
		g2d.drawImage(image, null, 0, 0);
	}

	private void paintBonuses(Graphics2D d2d) {
		for (Bonus bonus : AppCore.getInstance().getBonuses())
			bonus.paintBit(d2d);
	}

	private void paintWalls(Graphics2D d2d) {
		for (SnakeBits bit : AppCore.getInstance().getWalls())
			bit.paintBit(d2d);
	}

	private void paintSnake(Graphics2D g) {
		Snake.getInstance().paintSnake(g);
	}

	private void paintBoard(Graphics2D g) {
		Color old = g.getColor();
		g.setColor(AppCore.getInstance().getBoardColor());
		g.fillRect(AppCore.getInstance().getLeft(), AppCore.getInstance()
				.getTop(), AppCore.getInstance().getRight()
				- AppCore.getInstance().getLeft(), AppCore.getInstance()
				.getBottom() - AppCore.getInstance().getTop());
		// g.setColor(AppCore.getInstance().getGridColor());
		// for (int i = AppCore.getInstance().getLeft() + 10; i < AppCore
		// .getInstance().getRight(); i += 10)
		// g.drawLine(i, AppCore.getInstance().getTop(), i, AppCore
		// .getInstance().getBottom());
		// for (int i = AppCore.getInstance().getTop() + 10; i < AppCore
		// .getInstance().getBottom(); i += 10)
		// g.drawLine(AppCore.getInstance().getLeft(), i, AppCore
		// .getInstance().getRight(), i);
		g.setColor(AppCore.getInstance().getBorderColor());
		g.drawRect(AppCore.getInstance().getLeft(), AppCore.getInstance()
				.getTop(), AppCore.getInstance().getRight()
				- AppCore.getInstance().getLeft(), AppCore.getInstance()
				.getBottom() - AppCore.getInstance().getTop());
		g.setColor(old);
	}

	@Override
	public void dispose() {
		if (!disposed) {
			super.dispose();
			disposed = true;
		}
	}

	public boolean isDisposed() {
		return disposed;
	}

	public boolean isDisposingg() {
		return disposingg;
	}

	public void setDisposingg(boolean disposingg) {
		this.disposingg = disposingg;
	}

}
